/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package flange.functions;

/**
 *
 * @author Сергей
 */
abstract public class Function2D {
    private long width, height;
    private Point2D lt, rb;
    protected boolean okState;
    private double ymin = Double.POSITIVE_INFINITY, ymax = Double.NEGATIVE_INFINITY;
    abstract public double getY(double x);
    public void updateYbyMinMax() {
        lt.setY(ymin);
        rb.setY(ymax);
    }
    public void resetYbyMinMax() {
        lt.setY(Double.POSITIVE_INFINITY);
        rb.setY(Double.NEGATIVE_INFINITY);
    }
    public long getNormY(long x) {
        long y = 0;
        double dy;
        try {
            dy = getY(getXbyX(x));
            y = getYbyY(dy);
            okState = true;
            if (dy > ymax)
                ymax = dy;
            if (dy < ymin)
                ymin = dy;
        } catch (Exception e) {
            okState = false;
        }
        return y;
    }
    public boolean isOk() {
        return okState;
    }
    public Function2D() {
        width = 100;
        height = 100;
        lt = new Point2D(0,0);
        rb = new Point2D(100,100);
    }
    public Function2D(Point2D lt, Point2D rb) {
        this.width = 100;
        this.height = 100;
        this.lt = lt;
        this.rb = rb;
    }
    public void setPanelSize(long width, long height) {
        this.width = width;
        this.height = height;
    }

    public void setPanelDots( Point2D lt, Point2D rb ) {
        this.lt = lt;
        this.rb = rb;
    }

    public double getXbyX(long x) {
        return x * (rb.getX() - lt.getX())/width;
    }

    public double getYbyY(long y) {
        return (height - y) * (Math.abs(rb.getY() - lt.getY()))/height + lt.getY();
    }

    public long getYbyY(double y) {
        return Math.round(height - (y - lt.getY())/(Math.abs(rb.getY() - lt.getY())/height));
    }

    public long getY(long x) {
        return  getYbyY(getY(getXbyX(x)));
    }

    public void setDotsX(double x0, double x1) {
        lt.setX(x0);
        rb.setX(x1);
    }

}
